package com.weixin.reflection.proxy;

import java.io.ObjectInputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @ClassName ProxyTest
 * @Description 动态代理测试
 * @date 2022/2/21 13:37
 * @author: wx
 * @Version 1.0
 */
public class ProxyTest {
    public static void main(String[] args) {
        //被代理对象
        Proxys proxys = new Proxys();
        //动态代理工厂,此处的对象不能时proxys,否则代表该类·是代理类又是被代理类,只能使用强转为共同的接口
        //代理类与被代理类实现同一套接口
        ProxyInterface proxyInstance = (ProxyInterface) ProxyFactory.getProxyInstance(proxys);
        String length = proxyInstance.getLength();
        System.out.println("长度是：" + length);
        proxyInstance.eat("banana");
    }
}

class ProxyFactory {
    //使用此方法返回一个代理类的对象
    public static Object getProxyInstance(Object obj) {
        //通过反射的包获取代理对象
        MyInvocationHandler handler = new MyInvocationHandler();
        //用于绑定代理类
        handler.bind(obj);
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
    }
}

class MyInvocationHandler implements InvocationHandler {

    private Object obj;//使用对象暂代，在动态代理时进行处理

    public void bind(Object obj) {
        this.obj = obj;
    }

    //当我们通过代理类对象调用方法时，会自动调用如下方法
    //将被代理类将要执行的方法声明在invoke方法中去
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //此方法为需要调用的被代理类的方法
        //该方法的返回值就是invoke方法的返回值
        return method.invoke(obj, args);
    }
}